package rensoft.portfolio.client.model;

import static cs.java.lang.Lang.SECOND;
import static cs.java.lang.Lang.equal;
import static cs.java.lang.Lang.no;

import cs.java.lang.HasService;
import cs.java.lang.Run;
import cs.java.utility.RunConsolidator;


import rensoft.gwt.client.event.EventFunction;
import rensoft.gwt.client.history.HistoryItem;
import rensoft.gwt.client.history.HistoryItems;
import rensoft.gwt.client.lang.GwtBase;
import rensoft.portfolio.client.model.titles.Page;
import rensoft.portfolio.client.model.titles.Title;
import rensoft.portfolio.client.model.titles.Titles;
import rensoft.portfolio.client.model.titles.Titles.TitleState;

public class PageHistory extends GwtBase {

  private final HistoryItems items = new HistoryItems();
  private final HistoryItem pageItem = items.create("page", "");
  private final RunConsolidator consolidator = new RunConsolidator(SECOND / 2);

  public PageHistory(HasService value) {
    initialize(value);
    items.initialize(this);
  }

  public void initialize() {
    register(pageItem, HistoryItem.ON_CHANGE, new EventFunction<String>() {
      public void run(String value) {
        loadFromPageHistoryItem(value);
      }
    });
    register(getTitles(), Titles.ON_CHANGE, new EventFunction<Title>() {
      public void run(Title value) {
        onTitleChange(value);
      }
    });
    loadFromPageHistoryItem(pageItem.getValue());
  }

  private Titles getTitles() {
    return get(Titles.class);
  }

  private void loadFromPageHistoryItem(final String pageid) {
    consolidator.invoke(new Run() {
      public void run() {
        for (final Title title : getTitles())
          for (Page page : title)
            if (equal(pageid, page.getId())) {
              title.showPage(pageid);
              getTitles().open(title.getType());
              return;
            }
        getTitles().open(TitleState.closed);
      }
    });
  }

  private void onTitleChange(Title title) {
    if (no(title)) {
      pageItem.save("");
      unregister(Title.ON_PAGE_CHANGE);
    } else {
      pageItem.save(title.getPage().getId());
      registerReplace(title, Title.ON_PAGE_CHANGE, new EventFunction<Page>() {
        public void run(Page value) {
          pageItem.save(value.getId());
        }
      });
    }
  }
}
